package com.lincoln.framework.interfaces;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 带消息号的设备信息
 *
 * @param <T>
 * @author lincoln
 */
public abstract class MsgNoDeviceInfo<T> extends BaseDeviceInfo<T> {
    /**
     * 消息号最大值
     */
    private static final int NO_MAX = 255;
    /**
     * 消息号队列
     */
    public ConcurrentLinkedQueue<Integer> noQueue = new ConcurrentLinkedQueue<>();
    /**
     * 已使用的消息号,消息号-命令
     */
    public ConcurrentHashMap<Integer, byte[]> waitNo = new ConcurrentHashMap<>();

    public int getNo(byte[] cmd) {
        if (noQueue == null || noQueue.size() <= 0) {
            noQueue = new ConcurrentLinkedQueue<>();
            for (int i = 0; i < NO_MAX; i++) {
                noQueue.add(i);
            }
        }
        int res = noQueue.poll();
        if (waitNo == null) {
            waitNo = new ConcurrentHashMap<>(NO_MAX);
        }
        waitNo.put(res, cmd);
        return res;
    }

    /**
     * 释放消息号
     *
     * @param no
     */
    public void addNo(int no) {
        noQueue.add(no);
        waitNo.remove(no);
    }

    /**
     * 校验消息号
     *
     * @param no
     * @param cmd
     * @return
     */
    public boolean checkNo(int no, byte[] cmd) {
        if (waitNo == null) {
            waitNo = new ConcurrentHashMap<>(NO_MAX);
        }
        byte[] c = waitNo.get(no);
        if (c != cmd) {
            return false;
        }
        return true;
    }
}
